package mpbe.estructura.secciones.hormigon_armado;

/*
 * Este codigo es software libre y se encuentra licenciado 
 * bajo los términos de la Licencia Pública General de GNU versión 3 
 * según se encuentra publicada por la Free Software Foundation.
 * http://www.gnu.org/licenses/gpl.html
 * 
 * Autor: Martin Pablo Bellanca <martin.bellanca@gmail.com>
 * web: http://mpbe.blogspot.com/
 */

import java.io.File;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.text.NumberFormat;
import java.util.Iterator;
import java.util.Vector;

import org.eclipse.swt.widgets.ProgressBar;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;

import mpbe.estructura.Material;
import mpbe.estructura.Unidad;
import mpbe.estructura.secciones.Seccion;
import mpbe.estructura.secciones.hormigon_armado.contornos.SHContorno;
import mpbe.geometria.Limites;
import mpbe.geometria.Punto;

/**
 * @author  mpbe
 */
public class Hormigon_armado extends Seccion {
	private SHGenerales generales;
//	private Vector<SHCarga> cargas;
	public SHCargas cargas;
//	private Vector<SHContorno> contornos;
	public SHContornos contornos; 
//	private Vector<SHGrupo_de_Barras> grupos;
	public SHGrupos grupos;
	private SHFlexion flexion;
	private String marca; //la marca indica el estado de la seccion (Tilde, OK, Descartada, etc)
	
	private boolean guardar; //guarda si hubo cambios para guardar el archivo
	
	
	//-------------------------------------
	// Constructores
	//-------------------------------------
	public Hormigon_armado() {
		// definicion de variables internas
		generales = new SHGenerales();
		cargas = new SHCargas();
		contornos = new SHContornos();
		grupos = new SHGrupos();
		flexion = new SHFlexion();
		marca = "";
		guardar = true;	
		
		// TODO Agregados para pruebas sacar
		SHGrupo_de_Barras gb= grupos.get(0);
		gb.barras.add(new Barra_Redonda());
		
	}

	
	@Override
	public double getArea() {
		return contornos.getArea();
	}
	@Override
	public double getInercia() {
		return contornos.getInercia();
	}
	@Override
	public double getMtoEstatico() {
		return contornos.getMtoEstatico();
	}
	public double geth() {
		Limites extremos = contornos.getLimitesV();
		double d = Math.abs(extremos.max - extremos.min);
		double h = 0, hh=0;
		SHGrupo_de_Barras GB;
		GB = grupos.get(0); 
		h = GB.getYmin();
		for (int gg=0; gg<grupos.size(); gg++){
			GB = grupos.get(gg);
			if (GB.activo) {
				hh = GB.getYmin();
				if (hh<h) h=hh;
			}
		}
		return extremos.max-h;
	}
	
	
	
	public void copyInto (Hormigon_armado ha)
	{
		generales.copyInto(ha.generales);
		cargas.copyInto(ha.cargas.getCargas());
		contornos.copyInto(ha.contornos.getContornos());
		grupos.copyInto(ha.grupos.getGrupos());
		flexion.copyInto(ha.flexion);
		marca = ha.getMarca().trim();
		
		ha.guardar = true;
	}
	
	//-------------------------------------
	// delegados de Material y Unidades
	//-------------------------------------	
	@Override
	public Material getMaterial() {return generales.hormigon;}

	@Override
	public Unidad getULongitud() {return generales.uLongitud;}
	public Unidad getUFuerza() {return generales.uFuerza;}
	
	@Override
	public void setMaterial(Material material) {generales.hormigon = material;}

	@Override
	public void setULongitud(Unidad unidad) {generales.uLongitud = unidad;}
	public void setUFuerza(Unidad unidad) {generales.uFuerza = unidad;}

	
	//-------------------------------------
	// delegados de Generales
	//-------------------------------------
	public boolean equalsGenerales(Object obj) {
		return generales.equals(obj);
	}
	public String toStringGenerales() {
		return generales.toString();
	}
	/**
	 * @return
	 * @uml.property  name="generales"
	 */
	public SHGenerales getGenerales() {
		return generales;
	}
	/**
	 * @param generales
	 * @uml.property  name="generales"
	 */
	public void setGenerales(SHGenerales generales) {
		if (!(this.generales.equals(generales))) {
			guardar = true;
			if (!this.generales.uLongitud.equals(generales.uLongitud)
					||!this.generales.uFuerza.equals(generales.uFuerza)
					||!this.generales.hormigon.equals(generales.hormigon)
					||!this.generales.acero.equals(generales.acero)) {
				flexion.recalcular = true;
			}
		}
		this.generales = generales;
		
	}

	
	//-------------------------------------
	// delegados de Marca
	//-------------------------------------
	/**
	 * @return
	 * @uml.property  name="marca"
	 */
	public String getMarca() {
		return marca;
	}
	/**
	 * @param marca
	 * @uml.property  name="marca"
	 */
	public void setMarca(String marca) {
		this.marca = marca;
	}
	
	
	//------------------------------------
	// Funciones de Resultados, Guardar, Recalcular
	//------------------------------------
	/**
	 * @return
	 * @uml.property  name="guardar"
	 */
	public boolean getGuardar() {
		return guardar;
	}
	/**
	 * @return
	 * @uml.property  name="resultados"
	 */
	public SHFlexion getResultados() {
		return flexion;
	}
	
		
	//**********************************
	// Funciones de modificacion
	//**********************************
	public void mod_InvertirV(){
		// invierte contornos, grupos de barras y cargas
		contornos.mod_InvertirV();
		grupos.mod_InvertirV();
		cargas.mod_InvertirV();
	}
	public void mover(double deltaX, double deltaY) {
		contornos.mover(deltaX, deltaY);
		grupos.mover(deltaX, deltaY);
	}
	public void rotar(double grados){
		contornos.rotar(grados);
		grupos.rotar(grados);
	}
	public boolean mover_a_G(){
		double area = getArea();
		double ms = getMtoEstatico();
		double Yg = redondear(-ms/area);
		mover(0,Yg);
		return true;
	}
	private double redondear(double valor){
		double decRedondeo = generales.uLongitud.Coef*100;
		return ((double)Math.round(valor*decRedondeo)/decRedondeo);
	}
	
	
	//*****************************************************
	// Funciones JSON
	//*****************************************************
	public void put_JSON(JSONObject jo){
		
		JSONObject joa = new JSONObject();
		joa = (JSONObject) jo.get("Generales");
		generales.put_JSON(joa);
		
		JSONArray ja = new JSONArray();
		ja = (JSONArray) jo.get("Cargas");
		cargas.put_JSON(ja);
		/*cargas.clear();
		SHCarga cc;
		for (int ii=0; ii<ja.size(); ii++) {
			joa = (JSONObject) ja.get(ii);
			cc = new SHCarga();
			cc.put_JSON(joa);
			cargas.add(cc);
		}*/
		
		ja = (JSONArray) jo.get("Contornos");
		contornos.put_JSON(ja);
		/*contornos.clear();
		SHContorno co;
		for (int ii=0; ii<ja.size(); ii++) {
			joa = (JSONObject) ja.get(ii);
			co = new SHContorno();
			co.put_JSON(joa);
			contornos.add(co);
		}*/
		
		ja = (JSONArray) jo.get("Grupos de Barras");
		grupos.put_JSON(ja);
		/*grupos.clear();
		SHGrupo_de_Barras gg;
		for (int ii=0; ii<ja.size(); ii++) {
			joa = (JSONObject) ja.get(ii);
			gg = new SHGrupo_de_Barras();
			gg.put_JSON(joa);
			grupos.add(gg);
		}*/
		joa = (JSONObject) jo.get("Flexion");
		flexion.put_JSON(joa);
		
		marca = (String) jo.get("Marca");
		
		contornos.setIntervaloCalculo((Double) jo.get("Intervalo de Calculo"));
	}
	public JSONObject get_JSONObject() {
		JSONObject jo = new JSONObject();
		jo.put("Generales",	generales.get_JSONObject());
		
		
		JSONArray ja = cargas.get_JSONArray();
		/*SHCarga cc = new SHCarga();
		for (int ii=0; ii<cargas.size(); ii++) {
			cc = cargas.get(ii);
			ja.add(cc.get_JSONObject());
		}*/
		jo.put("Cargas", ja);
		
		//ja.clear();
		ja = contornos.get_JSONArray();
		/*SHContorno co = new SHContorno();
		for (int ii=0; ii<contornos.size(); ii++) {
			co = contornos.get(ii);
			ja.add(co.get_JSONObject());	
		}*/
		jo.put("Contornos", ja);
		
		//ja.clear();
		ja = grupos.get_JSONArray();
		/*SHGrupo_de_Barras gg = new SHGrupo_de_Barras();
		for (int ii=0; ii<grupos.size(); ii++) {
			gg = grupos.get(ii);
			ja.add(gg.get_JSONObject());
		}*/
		jo.put("Grupos de Barras", ja);
		
		jo.put("Flexion", flexion.get_JSONObject());
		
		jo.put("Marca", marca);
		
		jo.put("Intervalo de Calculo", contornos.getIntervaloCalculo());
		
		return jo;
	}
	public String get_JSONString(int tab) {
		
		String res = tabs(tab)+"{\n";
		res += tabs(tab+1)+"\"Generales\":\n"+generales.get_JSONString(tab+1)+",\n";
		
		res += tabs(tab+1)+"\"Cargas\":\n";
		res += cargas.get_JSONString(tab+1);
		/*res += tabs(tab+1)+"[\n";
		SHCarga cc = new SHCarga();
		for (int ii=0; ii<cargas.size(); ii++) {
			cc = cargas.get(ii);
			res += cc.get_JSONString(tab+2);
			if (ii==cargas.size()-1) res += "\n"+tabs(tab+1)+"],\n"; else res += ",\n";
		}*/
		
		res += tabs(tab+1)+"\"Contornos\":\n";
		res += contornos.get_JSONString(tab+1);
		/*res += tabs(tab+1)+"[\n";
		SHContorno co = new SHContorno();
		for (int ii=0; ii<contornos.size(); ii++) {
			co = contornos.get(ii);
			res += co.get_JSONString(tab+2);
			if (ii==contornos.size()-1) res += "\n"+tabs(tab+1)+"],\n"; else res += ",\n";
		}*/
		
		res += tabs(tab+1)+"\"Grupos de Barras\":\n";
		res += grupos.get_JSONString(tab+1);
		/*res += tabs(tab+1)+"[\n";
		SHGrupo_de_Barras gb = new SHGrupo_de_Barras();
		for (int ii=0; ii<grupos.size(); ii++) {
			gb = grupos.get(ii);
			res += gb.get_JSONString(tab+2);
			if (ii==grupos.size()-1) res += "\n"+tabs(tab+1)+"],\n"; else res += ",\n";
		}*/
		
		res += tabs(tab+1)+"\"Flexion\":\n"+flexion.get_JSONString(tab+1)+",\n";

		res += tabs(tab+1)+"\"Marca\":\""+marca+"\",\n";
		res += tabs(tab+1)+"\"Intervalo de Calculo\":"+contornos.getIntervaloCalculo()+"\n";
		res += tabs(tab)+"}";
		
		return res;
	}
	private String tabs(int can) {
		String str = new String();
		for (int ii=0; ii<can; ii++) str += "   "; // \t
		return str;
	}
	
	//*****************************************************
	// Funciones de lectura y escritura en archivo
	//*****************************************************
	public boolean saveas (String file) {
		FileOutputStream fout;	
		boolean res = true;
		try
		{
		    // Open an output stream
		    fout = new FileOutputStream (file);

		    // Print a line of text
		    String ss = this.get_JSONString(0);
		    new PrintStream(fout).println (ss);
		    
		    // Close our output stream
		    fout.close();		
		}
		// Catches any error conditions
		catch (IOException e)
		{
			System.err.println ("Unable to write to file");
			//System.exit(-1);
			res = false;
		}
		
		return res;
	}
	public boolean loadas (String file) {
		boolean res = true;
		try
		{
			FileReader fin = new FileReader (file);
			try {
				JSONParser jp = new JSONParser();
				JSONObject joSeccion = new JSONObject();
				joSeccion=(JSONObject)jp.parse(fin); //Crea el objeto JSON de la seccion
				put_JSON(joSeccion);
				
			} catch (Exception e) {
				System.out.println("Error en el parse");
				e.printStackTrace();
			}
			fin.close();	
			
		}
		// Catches any error conditions
		catch (IOException e)
		{
			System.err.println ("Unable to read to file");
			System.out.println("Error al leer el archivo");
			//System.exit(-1);
			res = false;
		}
		
		return res;
	}
}


